package io.boot.modules.monitor.controller;

import io.swagger.annotations.ApiOperation;
import io.boot.common.utils.Constant;
import io.boot.common.utils.R;
import io.boot.modules.monitor.dto.*;
import io.boot.modules.monitor.server.Server;
import org.hyperic.sigar.*;
import org.hyperic.sigar.Mem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;


/**
 * @author kyson
 * @date 2020/04/24 22:35
 */
@RestController
@RequestMapping("/monitor/server")
public class ServerController {


    protected static final Logger LOGGER = LoggerFactory.getLogger(ServerController.class);
    @Resource
    private RedisTemplate redisTemplate;

    @GetMapping("/info")
    public R info() throws Exception {
//        MonitorVO monitorVO = new MonitorVO();
//        Sigar sigar = new Sigar();
//        monitorVO.setCpu(cpuPerc(sigar));
//        monitorVO.setMemory(memory(sigar));
//        monitorVO.setDisk(file(sigar));
//        // 网络流量：查询最近
//        List<NetVO> list = redisTemplate.opsForList().range(Constant.MONITOR_NET, Constant.ZERO_LONG, (Constant.MONITOR_NET_GET - 1));
//        monitorVO.setNetList(list);
//        try{
//            sigar.close();
//        }catch (Exception e){
//            LOGGER.error("sigar close失败"+e.getMessage(), e);
//        }
//        return monitorVO;
        Server server = new Server();
        server.copyTo();
        return R.ok().put("server",server);
    }

    /**
     *  内存
     */
    private MemoryVO memory(Sigar sigar) throws SigarException {
        MemoryVO memoryVO = new MemoryVO();
        // 使用sigar获取内存
        Mem mem = sigar.getMem();
        double memTotal = mem.getTotal();
        double memRam = mem.getRam();
        double memUsed = mem.getActualUsed();
        double memFree = mem.getActualFree();
        double memUsedPerc = mem.getUsedPercent();
        memoryVO.setMemory(String.format("%.2f", memTotal / 1024 / 1024 / 1024) + "GB");
        memoryVO.setMemRam(String.format("%.2f", memRam / 1024) + "GB");
        memoryVO.setMemUsed(String.format("%.2f", memUsed / 1024 / 1024 / 1024) + "GB");
        memoryVO.setMemFrees(String.format("%.2f", memFree / 1024 / 1024 / 1024) + "GB");
        memoryVO.setMemoryUsage(String.format("%.2f", memUsedPerc) + "%");
        return memoryVO;
    }

    /**
     *  cpu使用率
     */
    private static CpuVO cpuPerc(Sigar sigar) throws SigarException {
        CpuPerc cpu = sigar.getCpuPerc();
        CpuVO cpuVO = new CpuVO();
        cpuVO.setUser(CpuPerc.format(cpu.getUser()));
        cpuVO.setSys(CpuPerc.format(cpu.getSys()));
        cpuVO.setWait(CpuPerc.format(cpu.getWait()));
        cpuVO.setNice(CpuPerc.format(cpu.getNice()));
        cpuVO.setIdle(CpuPerc.format(cpu.getIdle()));
        cpuVO.setCombined(CpuPerc.format(cpu.getCombined()));
        return cpuVO;
    }

    private DiskVO file(Sigar sigar) throws Exception {
        DiskVO diskVO = new DiskVO();
        long total = 0L;
        long free = 0L;
        long avail = 0L;
        long used = 0L;
        FileSystem fslist[] = sigar.getFileSystemList();
        for (int i = 0; i < fslist.length; i++) {
            FileSystem fs = fslist[i];
            FileSystemUsage usage = null;
            try {
                usage = sigar.getFileSystemUsage(fs.getDirName());
            } catch (SigarException e) {
                LOGGER.error("{}-- 不可用",fs.getDirName());
                continue;
            }
            switch (fs.getType()) {
                case 0: // TYPE_UNKNOWN ：未知
                    break;
                case 1: // TYPE_NONE
                    break;
                case 2: // TYPE_LOCAL_DISK : 本地硬盘
                    // 文件系统总大小
                    total += usage.getTotal();
                    // 文件系统剩余大小
                    free += usage.getFree();
                    // 文件系统可用大小
                    avail += usage.getAvail();
                    // 文件系统已经使用量
                    used += usage.getUsed();
                    break;
                case 3:// TYPE_NETWORK ：网络
                    break;
                case 4:// TYPE_RAM_DISK ：闪存
                    break;
                case 5:// TYPE_CDROM ：光驱
                    break;
                case 6:// TYPE_SWAP ：页面交换
                    break;
                default:
                    break;
            }
        }
        diskVO.setTotal(String.format("%.2f", total / 1024 / 1024D) + "GB");
        diskVO.setFree(String.format("%.2f", free / 1024 / 1024D) + "GB");
        diskVO.setAvail(String.format("%.2f", avail / 1024 / 1024D) + "GB");
        diskVO.setUsed(String.format("%.2f", used / 1024 / 1024D) + "GB");
        diskVO.setUsePercent(String.format("%.2f", 100D * used / total) + "%");
        return diskVO;
    }


}
